package com.dongdongshop.config;

import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

//springboot取消了配置文件，我们一般都是使用配置类来代替配置文件
@Component
@Aspect//表示当前类是一个切面类
public class LogAop {

    private Logger logger = LoggerFactory.getLogger(LogAop.class);

    //切点和通知

    //切点表达式(版本一）
//    @Pointcut("execution(* com.dongdongshop.service.*.*(..))")
//    public void pointcut(){
//
//    }

// 切点表达式(版本二）
//    //@annotation : 只切加了DongKeLog自定义注解的方法
//    @Pointcut("@annotation(com.dongdongshop.log.DongKeLog)")
//    public void pointcut(){
//
//    }

    // 切点表达式(版本三）
    //除了service全打之外，其他的，例如controller层有些想打有些不想打，所以加上了注解的就打，没加上就不打
    @Pointcut("execution(* com.dongdongshop.service.*.*(..)) || @annotation(com.dongdongshop.log.DongKeLog)")
    public void pointcut(){

    }

    //定义通知：前置，后置，环绕，返回，异常
    @Before("pointcut()")
    public void aopBefore(JoinPoint joinPoint){
        //前置通知打印参数,{}是占位符，joinPoint.getSignature()是打印当前方法名,args是参数
        Object[] args = joinPoint.getArgs();
        logger.info("正在调用 {} 方法，参数为 {}",joinPoint.getSignature(),args);
    }

    //返回后通知
    //Object obj返回后通知的结果
    //returning 指定返回的结果
    //JSONObject.toJSONString()，json转格式，用到了alibaba的json转换架包
    @AfterReturning(value = "pointcut()",returning = "obj")
    public void aopAfter(Object obj) throws Throwable{
        logger.info("方法调用成功，返回的结果为：{}", JSONObject.toJSONString(obj));
    }

}
